package com.strp.mptcp.ACK.manager;

import com.strp.mptcp.ACK.AckHeader;
import com.strp.mptcp.ACK.RetransmissionRequestHeader;
import com.strp.mptcp.ACK.SelectiveAckHeader;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;

public class AckManager {
    private static volatile Channel channel;

    /**
     * 在客户端／服务端启动时初始化，用于后续发送 ACK。
     */
    public static void init(Channel ch) {
        channel = ch;
    }

    /**
     * 发送普通 ACK，包含最大连续接收序列号。
     */
    public static void sendAck(AckHeader header) {
        if (channel != null && channel.isActive()) {
            ByteBuf buf = header.toByteBuf();
            channel.writeAndFlush(buf).addListener((ChannelFutureListener) future -> {
                if (!future.isSuccess()) {
                    System.err.println("Failed to send ACK: " + future.cause());
                }
            });
        }
    }

    /**
     * 发送选择性 ACK，请求对方重传指定的序列号列表。
     */
    public static void sendSelectiveAck(SelectiveAckHeader header) {
        if (channel != null && channel.isActive()) {
            ByteBuf buf = header.toByteBuf();
            channel.writeAndFlush(buf).addListener((ChannelFutureListener) future -> {
                if (!future.isSuccess()) {
                    System.err.println("Failed to send SACK: " + future.cause());
                }
            });
        }
    }

    /**
     * 请求重新发送指定的 seq
     */
    public static void requestRetransmission(long seq) {
        if (channel != null && channel.isActive()) {
            ByteBuf buf = new RetransmissionRequestHeader(seq).toByteBuf();
            channel.writeAndFlush(buf).addListener((ChannelFutureListener) future -> {
                if (!future.isSuccess()) {
                    System.err.println("Failed to send retransmission request: " + future.cause());
                }
            });
        }
    }

    /**
     * 发送窗口更新通知
     * @param windowStart 窗口起始序列号
     * @param windowEnd 窗口结束序列号
     */
    public static void sendWindowUpdate(long windowStart, long windowEnd) {
        if (channel != null && channel.isActive()) {
            ByteBuf buf = new WindowUpdateHeader(windowStart, windowEnd).toByteBuf();
            channel.writeAndFlush(buf).addListener((ChannelFutureListener) future -> {
                if (!future.isSuccess()) {
                    System.err.println("Failed to send window update: " + future.cause());
                }
            });
        }
    }

    /**
     * 窗口更新头部
     */
    private static class WindowUpdateHeader {
        private final long windowStart;
        private final long windowEnd;

        public WindowUpdateHeader(long windowStart, long windowEnd) {
            this.windowStart = windowStart;
            this.windowEnd = windowEnd;
        }

        public ByteBuf toByteBuf() {
            ByteBuf buf = channel.alloc().buffer(17); // 1 + 8 + 8
            buf.writeByte(0x04); // 窗口更新类型
            buf.writeLong(windowStart);
            buf.writeLong(windowEnd);
            return buf;
        }
    }
}

